/*
 * smushit-cli - A command line tool for the Yahoo! Smush.it API
 *
 * Copyright (c) 2010 Benjamin Schneider
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "ImageUploader.h"

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include "CurlErrorException.h"
#include "SmushResult.h"

namespace pt = boost::property_tree;

using std::string;
using std::stringstream;

namespace smushit_cli {

const char SMUSHIT_API_URL[] = "http://www.smushit.com/ysmush.it/ws.php";

ImageUploader::ImageUploader():
    myPostData(NULL) {

    SAFE_CURL(curl_easy_setopt(myCurlInstance, CURLOPT_URL, SMUSHIT_API_URL));
}

ImageUploader::~ImageUploader() {

    if (myPostData != NULL) {
        curl_formfree(myPostData);
    }
}

SmushResult ImageUploader::uploadImage(const string& file) {

    setupPostData(file);

    SAFE_CURL(curl_easy_perform(myCurlInstance));

    return generateResult();
}

void ImageUploader::setupPostData(const string& file) {

    struct curl_httppost* last = NULL;

    CURLFORMcode res = curl_formadd(
            &myPostData,
            &last,
            CURLFORM_COPYNAME, "files[0]",
            CURLFORM_FILE,     file.c_str(),
            CURLFORM_END
            );

    if (res != CURL_FORMADD_OK) {
        throw std::runtime_error("Curl form error");
    }

    SAFE_CURL(curl_easy_setopt(myCurlInstance, CURLOPT_POST,     true));
    SAFE_CURL(curl_easy_setopt(myCurlInstance, CURLOPT_HTTPPOST, myPostData));
}

SmushResult ImageUploader::generateResult() {

    string resultString = myResultStream.str();

    // Erase all backslashes that are used in the API result to mask
    // slashes in URLs
    boost::algorithm::erase_all(resultString, "\\");

    std::stringstream jsonStream;
    jsonStream << resultString;

    pt::ptree tree;
    pt::json_parser::read_json(jsonStream, tree);
    
    SmushResult result;
    
    if (tree.count("src")) {
        result.src = tree.get<string>("src");
    }
    
    if (tree.count("src_size")) {
        result.src_size = tree.get<unsigned int>("src_size");
    }
    
    if (tree.count("dest")) {
        result.dest = tree.get<string>("dest");
    }
    
    if (tree.count("dest_size")) {
        result.dest_size = tree.get<unsigned int>("dest_size");
    }
    
    if (tree.count("error")) {
        result.error = tree.get<string>("error");
    }

    return result;
}

}

